package stream;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import objectpack.Student;
import org.testng.Assert;
import org.testng.annotations.Test;

/**
 * Stream是一个并行计算框架
 *
 *
 * concat：concatenation，串联
 *
 * count: 计数
 */
public class Stream_1 {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(7, 6, 9,0, 3, 8, 2, 1);

        // 遍历输出符合条件的元素
        list.stream().filter(x -> x > 6).forEach(System.out::println);
        // 匹配第一个
        Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
        // 匹配任意（适用于并行流）
        Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();

        // 是否包含符合特定条件的元素
        boolean anyMatch = list.stream().anyMatch(x -> x < 6);

        System.out.println("匹配第一个值：" + findFirst.get());
        System.out.println("匹配任意一个值：" + findAny.get());
        System.out.println("是否存在大于6的值：" + anyMatch);

        //排序
        //数字：默认按升序

        list.stream().sorted().forEach(System.out::print);
        System.out.println();
        //字母：默认按升序
        Stream<String> stream = Stream.of("a","z","h","x","d","n","a");
        stream.sorted().forEach(System.out::print);

        //自定义排序规则
        List<Student> list1 = new ArrayList<>();
        list1.add(new Student("momo",23,"f"));
        list1.add(new Student("jomo",20,"m"));
        list1.add(new Student("alex",93,"f"));
        list1.add(new Student("holjl",3,"m"));

        //




    }

    /**
     * empty方法返回不为空
     */
    @Test
    public void t1() {
        Stream stream = Stream.empty();
        Assert.assertTrue(!Objects.isNull(stream));
    }

    /**
     * concat
     */
    @Test
    public void t2() {
        Stream<Map<Integer, Integer>> s1 = Stream.empty();
        Map<Integer, Integer> map = new HashMap<>();
        map.put(1, 1);
        map.put(2, 2);
        Stream<Map<Integer, Integer>> s2 = Stream.of(map);

        Map<Integer, Integer> map2 = new HashMap<>();
        map2.put(3, 3);

        Stream<Map<Integer, Integer>> s3 = Stream.of(map2);

        // 要注意concat的结果仍然是一个stream
//        Stream<Map<Integer, Integer>> s3 = Stream.concat(s1, s2);

//        Stream.concat(s1, s2).forEach(System.out::println);

        Stream.concat(s2, s3).forEach(System.out::println);

//        Object collect = s3.collect(Collectors.toSet());
//        System.out.println("s3 : " + collect);

        Map<Integer, Integer> map3 = new HashMap<>();
        map.put(3, 1);
        map.put(10, 2);
//        s3.forEach(System.out::println);

//        Stream concat = Stream.concat(s3, Stream.of(map2));

//        concat.forEach(System.out::println);
//        Object collect = concat.collect(Collectors.toMap(s -> s, v -> v));
//        System.out.println(collect);

    }

    @Test
    public void t3() {
        Stream s1 = Stream.of(1);
//        Stream.concat(Stream.of(2), Stream.of(5)).forEach(System.out::println);
        Stream<String> abc = Stream.concat(Stream.empty(), Stream.of("ABC"));
//        abc.forEach(System.out::println);
        abc.sorted().forEach(System.out::println);
    }

    /**
     * concat不会去重
     */
    @Test
    public void t4() {
        Stream.concat(Stream.of("a"), Stream.of("a")).forEach(System.out::println);

        Stream.concat(Stream.of(1), Stream.of(1)).forEach(System.out::println);

        // 主动调用去重函数才会去重
        Stream.concat(Stream.of(1), Stream.of(1)).distinct().forEach(System.out::println);
    }

    @Test
    public void t5() {
        Map<Integer, Integer> map = new HashMap();
        map.put(1, 1);
        map.put(2, 5);
//        Stream<Integer> s1 = Stream.of(map.values());

        Set<Integer> set = new HashSet<>();
        map.forEach((k, v) -> {
            set.add(v);
        });

        Stream<Integer> str = Stream.empty();

//        set.forEach(s -> {
//            str = Stream.concat(str, s);
//        });

    }

    /**
     * max处理相同的值的时候后出现的值不会替换已经出现的值
     */
    @Test
    public void t6() {
        Student s1 = new Student("a", 1, "f");
        Student s2 = new Student("b", 1, "f");
        Student s3 = new Student("c", 1, "f");

        var list = new ArrayList<Student>();
        list.add(s1);
        list.add(s2);
        list.add(s3);

        var set = list.stream()
            .max(Comparator.comparingInt(Student::getAge))
            .stream().collect(Collectors.toSet());

        System.out.println(set);
    }

    /**
     * findAny
     */
    @Test
    private void t7() {
        var set = new HashSet<String>();
        set.add("a");
        set.add("b");

        var res = set.stream()
            .filter("b"::equals)
            .findAny();
        Assert.assertFalse(res.isEmpty(), "");

        var res2 = set.stream()
            .filter("c"::equals)
            .findAny();
        Assert.assertTrue(res2.isEmpty(), "");
    }

    /**
     *
     */
    private void t8() {
        Queue<Integer> queue = new ArrayDeque<>();
        // 得到的是非并行流
        queue.stream().collect(Collectors.toList());
    }

    /**
     *
     */
    @Test
    private void t9() {
        Student s1 = new Student("a", 2, "f");
        Student s2 = new Student("b", 1, "f");
        Student s3 = new Student("c", 3, "f");

        var n = List.of(s1, s2, s3).stream()
            .filter(s -> s.getAge() > 1)
            .count();
        System.out.println(n);
    }

}


